package br.unifor.cct.mia.xover;

import br.unifor.cct.mia.evolutionary.Genotype;
import br.unifor.cct.mia.ga.Ga;
import br.unifor.cct.mia.util.Methods;

public class XOverPBXCU extends XOver {

	private void xover(Ga Ga) {
        if (Ga.configurations.getNvars() > 1) {
        	        	
        	int size = ((Genotype)Ga.population[one]).getGene().length-2;
        	
        	double pai1[] = ((Genotype)Ga.population[one]).getGene();
        	double pai2[] = ((Genotype)Ga.population[two]).getGene();
        	
        	int points[] = new int[size/2];
        	
        	for ( int i=0; i<points.length; i++ ) {
        		int val = Methods.randIntValue(0,size);
        		while ( Methods.arrayContains(points,val) ) {
        			val = Methods.randIntValue(0,size);
        		}
        		points[i] = val;
        	}
        	            
            double filho1[] = new double[size+2];
            double filho2[] = new double[size+2];
            
            filho1[size] = pai2[size];
            filho1[size+1] = pai2[size+1];
            
            filho2[size] = pai1[size];
            filho2[size+1] = pai1[size+1];
            
            for ( int i=0; i<points.length; i++ ) {
            	filho1[points[i]] = pai2[points[i]];	
            }
            
            for ( int i=0; i<size; i++ ) {
            	if ( Methods.arrayContains(points,i) ) continue;
            	if ( !Methods.arrayContains(filho1,pai1[i]) ) {
            		filho1[i] = pai1[i];
            	}
            }
            
            for ( int i=0; i<points.length; i++ ) {
            	filho2[points[i]] = pai1[points[i]];	
            }
                        
            for ( int i=0; i<size; i++ ) {
            	if ( Methods.arrayContains(points,i) ) continue;
            	if ( !Methods.arrayContains(filho2,pai1[2]) ) {
            		filho2[i] = pai2[i];
            	}
            }
        }
	}
	
	public Object execute(Object value) {
    	Object[] o = (Object[])value;
		Ga Ga = (Ga)o[0];
		
		xover(Ga);
		return Ga.population;
	}
}